/**
 * ThirdPartyParserFactory.java
 * author: yujiakui
 * 2017年8月29日
 * 上午11:54:42
 */
package com.ctim.service.integration.parser;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.ctim.common.exception.PcsRunTimeException;
import com.ctim.service.enums.ParserTypeEnum;
import com.google.common.collect.Maps;

/**
 * @author yujiakui
 *
 *         上午11:54:42
 *
 */
@Component
public class ThirdPartyParserFactory implements ApplicationContextAware, InitializingBean {

	/** spring 上下文 */
	private ApplicationContext applicationContext;

	/** 解析器映射map */
	private static Map<ParserTypeEnum, ThirdPartyResponseParser> parserMaps = Maps.newHashMap();

	/**
	 * 根据类型获取对应的解析器
	 *
	 * @param type
	 * @return
	 */
	public static ThirdPartyResponseParser getParserByType(ParserTypeEnum type) {
		ThirdPartyResponseParser thirdPartyResponseParser = parserMaps.get(type);
		if (null == thirdPartyResponseParser) {
			throw new PcsRunTimeException(MessageFormat.format("类型type={0}对应的解析器不存在map={1}", type, parserMaps));
		}
		return thirdPartyResponseParser;
	}

	/*
	 *
	 * @see
	 * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		// 获取实现parser接口的bean，然后将这种bean注入到工厂的map中
		Map<String, ThirdPartyResponseParser> parserBeanMap = applicationContext
				.getBeansOfType(ThirdPartyResponseParser.class);
		// 防止并发情况注入
		Map<ParserTypeEnum, ThirdPartyResponseParser> tempParserMap = Maps.newHashMap(parserMaps);
		for (Map.Entry<String, ThirdPartyResponseParser> entryEle : parserBeanMap.entrySet()) {
			ThirdPartyResponseParser thirdPartyResponseParser = entryEle.getValue();
			List<ParserTypeEnum> parserTypeEnums = thirdPartyResponseParser.getParseTypes();
			for (ParserTypeEnum parserTypeEnum : parserTypeEnums) {
				ThirdPartyResponseParser tempParser = tempParserMap.get(parserTypeEnum);
				if (null != tempParser) {
					if (!tempParser.equals(thirdPartyResponseParser)) {
						throw new PcsRunTimeException(MessageFormat.format("在解析器工厂中进行注入得到同一个type={0}对应多个解析器对象={1},{2}",
								parserTypeEnum, thirdPartyResponseParser, tempParser));
					}
				} else {
					tempParserMap.put(parserTypeEnum, thirdPartyResponseParser);
				}
			}

		}

		parserMaps = tempParserMap;
	}

	/*
	 *
	 * @see
	 * org.springframework.context.ApplicationContextAware#setApplicationContext
	 * (org.springframework.context.ApplicationContext)
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

}
